/*
 * Copyright (C) 2009 codemobiles.com.
 * http://www.codemobiles.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * author: Chaiyasit Tayabovorn 
 * email: chaiyasit.t@gmail.com
 */

package com.codemobiles.droidslator_tattoo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Point;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * This class is extended from View and responsible for managing all objects
 * used to configure between from/to translation languages.
 * 
 * @author jaboho
 * 
 */
public class SelectionView extends View {
  private RegionSpec fromLangSpec;
  private RegionSpec toLangSpec;
  private SimpleImage fromLangFlagImage;
  private SimpleImage toLangFlagImage;
  private SimpleImage tmpFlagImage;
  private SimpleImage focusImage;
  private RegionSpec focusReg;
  private RegionSpec anotherReg;
  private int IMAGE_WIDTH;
  private int IMAGE_HEIGHT;
  private String POS_LOG = "POS_LOG";
  private final int POINT1_X = 0;
  private final int POINT1_Y = 15;
  private final int POINT2_X = 0;
  private final int POINT2_Y = 50;
  private boolean isHalfOpacity = false;
  // keep selected region
  private static final int FROM_REGION = 0;
  private static final int TO_REGION = 1;
  private int startReg;
  private int lastReg;
  private String lastRegStr;

  private long startTouchTime = 0; // keep touch hold time

  private Droidslator droidslator;

  public SelectionView(Context context) {
    super(context);
    setFocusable(true); // necessary for getting the touch events
    droidslator = (Droidslator) context;

    // POINT 1/2
    Point point1 = new Point(POINT1_X, POINT1_Y);
    Point point2 = new Point(POINT2_X, POINT2_Y);

    // FORM IMAGES
    fromLangFlagImage = new SimpleImage(context, R.drawable.flag_en, point1, true, "en");
    toLangFlagImage = new SimpleImage(context, R.drawable.flag_th, point2, true, "th");

    // LOAD TEMPLATE OF IMAGE
    IMAGE_WIDTH = fromLangFlagImage.getWidth();
    IMAGE_HEIGHT = fromLangFlagImage.getHeight();

    // FORM REGION SPEC.
    fromLangSpec = new RegionSpec(POINT1_X, POINT1_Y, IMAGE_WIDTH, IMAGE_HEIGHT);
    toLangSpec = new RegionSpec(POINT2_X, POINT2_Y, IMAGE_WIDTH, IMAGE_HEIGHT);

    // BIND REGION SPEC WITH INITAIL IMAGE
    fromLangSpec.setBoundObject(fromLangFlagImage);
    toLangSpec.setBoundObject(toLangFlagImage);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    // draw the images on the canvas
    canvas.drawBitmap(fromLangFlagImage.getBitmap(), fromLangFlagImage.getX(), fromLangFlagImage.getY(), null);
    canvas.drawBitmap(toLangFlagImage.getBitmap(), toLangFlagImage.getX(), toLangFlagImage.getY(), null);
  }

  // events when touching the screen
  public boolean onTouchEvent(MotionEvent event) {
    int eventaction = event.getAction();
    int X = (int) event.getX();
    int Y = (int) event.getY();

    try {
      switch (eventaction) {

      case MotionEvent.ACTION_DOWN:
        // keep time
        startTouchTime = System.currentTimeMillis();

        // keep initial region
        setInitialReg(X, Y);

        focusReg = getFocusRegionSpec(X, Y);
        if (focusReg != null) {
          focusImage = (SimpleImage) focusReg.getBoundObject();
        }
        break;

      case MotionEvent.ACTION_MOVE:
        // move the image followed finger
        if (focusImage != null) {
          // focusImage.setX(X - 25); // disable x move
          focusImage.setY(Y - 25);
          if (!isHalfOpacity) {
            focusImage.halfOpacity();
            isHalfOpacity = true;
          }
        }

        if ((getFocusRegionSpec(X, Y) != null) && (focusImage != null)) {
          focusReg = getFocusRegionSpec(X, Y);
          anotherReg = getAnotherRegionSpec(focusReg);
          if (!focusReg.isCurrentBoundObject(focusImage)) {
            tmpFlagImage = ((SimpleImage) anotherReg.getBoundObject());

            ((SimpleImage) focusReg.getBoundObject()).setPosition(anotherReg);
            anotherReg.setBoundObject(focusReg.getBoundObject());
            focusReg.setBoundObject(tmpFlagImage);
            tmpFlagImage = null;
            droidslator.setTranslateTitle();
            // droidslator.swapText();

            // swap region
            if (lastReg == FROM_REGION) {
              lastReg = TO_REGION;
            } else {
              lastReg = FROM_REGION;
            }
            Log.i("POS_TAG", "startReg=" + startReg);
            Log.i("POS_TAG", "lastReg=" + lastReg);
          }
        }

        if (Y - 25 < POINT1_Y) {
          focusImage.setY(POINT1_Y);
        } else if (Y - 25 > POINT2_Y) {
          focusImage.setY(POINT2_Y);
        }
        break;

      case MotionEvent.ACTION_UP:
        if (focusImage != null) {
          if (isHalfOpacity) {
            focusImage.restoreOpacity();
            isHalfOpacity = false;
            focusImage.setPosition(focusReg);
            focusReg.setBoundObject(focusImage);
          }
          setTitleID();
          // check flag selected doesn't swap
          if (checkSameReg(focusImage) && System.currentTimeMillis() - startTouchTime < 500) { // check
                                                                                          // list
            setTitleID();
            if (lastReg == FROM_REGION) {
              lastRegStr = "Translate From";
            } else if (lastReg == TO_REGION) {
              lastRegStr = "Translate To";
            }
            droidslator.showList(focusImage, lastRegStr);
          }
          startTouchTime = System.currentTimeMillis();
          Log.i(POS_LOG, "fromLang: " + ((SimpleImage) fromLangSpec.getBoundObject()).getID());
          Log.i(POS_LOG, "toLang: " + ((SimpleImage) toLangSpec.getBoundObject()).getID());
        }
        focusImage = null;
        break;
      }

      // redraw the canvas
      invalidate();
      return true;
    } catch (Exception e) {
      invalidate();
      return true;
    }

  }

  private boolean checkSameReg(SimpleImage img) {
    if (startReg != lastReg) {
      return false;
    }

    return true;
  }

  private void setTitleID() {
    // check focus image is from or to image
    if (focusReg.equals(fromLangSpec)) {
      focusImage.setTitleID(R.string.select_dialog_from);
    } else if (focusReg.equals(toLangSpec)) {
      focusImage.setTitleID(R.string.select_dialog_to);
    }
  }

  private void setInitialReg(int X, int Y) {
    if (X > fromLangSpec.getX() && X < fromLangSpec.getX() + fromLangSpec.getWidth() && Y > fromLangSpec.getY()
        && Y < fromLangSpec.getY() + fromLangSpec.getHeight()) {
      startReg = FROM_REGION;
      lastReg = FROM_REGION;

    } else if (X > toLangSpec.getX() && X < toLangSpec.getX() + toLangSpec.getWidth() && Y > toLangSpec.getY()
        && Y < toLangSpec.getY() + toLangSpec.getHeight()) {
      startReg = TO_REGION;
      lastReg = TO_REGION;
    }
  }

  private RegionSpec getFocusRegionSpec(int X, int Y) {

    if (X > fromLangSpec.getX() && X < fromLangSpec.getX() + fromLangSpec.getWidth() && Y > fromLangSpec.getY()
        && Y < fromLangSpec.getY() + fromLangSpec.getHeight()) {
      return fromLangSpec;

    } else if (X > toLangSpec.getX() && X < toLangSpec.getX() + toLangSpec.getWidth() && Y > toLangSpec.getY()
        && Y < toLangSpec.getY() + toLangSpec.getHeight()) {
      return toLangSpec;
    }
    return null;
  }

  private RegionSpec getAnotherRegionSpec(RegionSpec regSpec) {
    if (regSpec.equals(fromLangSpec)) {
      return toLangSpec;
    } else {
      return fromLangSpec;
    }
  }

  public boolean checkFlagDup(String flagName) {
    boolean ret = false;
    Log.i("POS_TAG", "checkFlagDup = " + (fromLangFlagImage.getID().equals(flagName) && toLangFlagImage.getID().equals(flagName)));
    Log.i("POS_TAG", "Before fromLangFlagImage = " + fromLangFlagImage.getID());
    Log.i("POS_TAG", "Before toLangFlagImage = " + toLangFlagImage.getID());

    if (fromLangFlagImage.getID().equals(flagName) && toLangFlagImage.getID().equals(flagName)) {
      ret = true;
    }
    return ret;
  }

  public boolean setBitmapFile(String fileName, SimpleImage img) {
    if (img != null) {
      int flagID = droidslator.getResources().getIdentifier("flag_" + fileName, "drawable", "com.codemobiles.droidslator_tattoo");
      if (!checkFlagDup(fileName)) {
        img.reDrawImage(flagID, fileName);
        // redraw the canvas
        invalidate();
        Log.i("POS_TAG", "After fromLangFlagImage = " + fromLangFlagImage.getID());
        Log.i("POS_TAG", "After toLangFlagImage = " + toLangFlagImage.getID());
        Log.i("POS_TAG", "After img = " + img.getID());
        return true;
      }
    }
    return false;
  }

  public String getFromFlagCode() {
    return ((SimpleImage) fromLangSpec.getBoundObject()).getID();
  }

  public String getToFlagCode() {
    return ((SimpleImage) toLangSpec.getBoundObject()).getID();
  }
}
